<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Bug 663570 - Implement Content Security Policy via meta tag</title>
  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<iframe style="width:100%;" id="testframe"></iframe>

<script class="testbody" type="text/javascript">

/* Description of the test:
 * We test all sorts of CSPs on documents, including documents with no
 * CSP, with meta CSP and with meta CSP in combination with a CSP header.
 */

const TESTS = [
  {
    /* load image without any CSP */
    query: "test1",
    result: "img-loaded",
    policyLen: 0,
    desc: "no CSP should allow load",
  },
  {
    /* load image where meta denies load */
    query: "test2",
    result: "img-blocked",
    policyLen: 1,
    desc: "meta (img-src 'none') should block load"
  },
  {
    /* load image where meta allows load */
    query: "test3",
    result: "img-loaded",
    policyLen: 1,
    desc: "meta (img-src http://mochi.test) should allow load"
  },
  {
    /* load image where meta allows but header blocks */
    query: "test4", // triggers speculative load
    result: "img-blocked",
    policyLen: 2,
    desc: "meta (img-src http://mochi.test), header (img-src 'none') should block load"
  },
  {
    /* load image where meta blocks but header allows */
    query: "test5", // triggers speculative load
    result: "img-blocked",
    policyLen: 2,
    desc: "meta (img-src 'none'), header (img-src http://mochi.test) should block load"
  },
  {
    /* load image where meta allows and header allows */
    query: "test6", // triggers speculative load
    result: "img-loaded",
    policyLen: 2,
    desc: "meta (img-src http://mochi.test), header (img-src http://mochi.test) should allow load"
  },
  {
    /* load image where meta1 allows but meta2 blocks */
    query: "test7",
    result: "img-blocked",
    policyLen: 2,
    desc: "meta1 (img-src http://mochi.test), meta2 (img-src 'none') should allow blocked"
  },
  {
    /* load image where meta1 allows and meta2 allows */
    query: "test8",
    result: "img-loaded",
    policyLen: 2,
    desc: "meta1 (img-src http://mochi.test), meta2 (img-src http://mochi.test) should allow allowed"
  },
];

var curTest;
var counter = -1;

function finishTest() {
  window.removeEventListener("message", receiveMessage, false);
  SimpleTest.finish();
}

function checkResults(result) {
  // make sure the image got loaded or blocked
  is(result, curTest.result, curTest.query + ": " + curTest.desc);

  if (curTest.policyLen != 0) {
    // make sure that meta policy got not parsed and appended twice
    try {
      // get the csp in JSON notation from the principal
      var frame = document.getElementById("testframe");
      var principal = SpecialPowers.wrap(frame.contentDocument).nodePrincipal;
      var cspJSON = principal.cspJSON;
      var cspOBJ = JSON.parse(cspJSON);

      // make sure that the speculative policy and the actual policy
      // are not appended twice.
      var policies = cspOBJ["csp-policies"];
      is(policies.length, curTest.policyLen, curTest.query + " should have: " + curTest.policyLen + " policies");
    }
    catch (e) {
      ok(false, "uuh, something went wrong within cspToJSON in " + curTest.query);
    }
  }
  // move on to the next test
  runNextTest();
}

// a postMessage handler used to bubble up the
// onsuccess/onerror state from within the iframe.
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
  checkResults(event.data.result);
}

function runNextTest() {
  if (++counter == TESTS.length) {
    finishTest();
    return;
  }
  curTest = TESTS[counter];
  // load next test
  document.getElementById("testframe").src = "file_meta_header_dual.sjs?" + curTest.query;
}

// start the test
SimpleTest.waitForExplicitFinish();
runNextTest();

</script>
</body>
</html>
